package com.fortune.common.spring.config;

import java.util.List;
import java.util.Set;

import javax.servlet.http.HttpServletRequest;
import javax.validation.ConstraintViolation;
import javax.validation.ConstraintViolationException;

import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.core.env.ConfigurableEnvironment;
import org.springframework.validation.BindException;
import org.springframework.validation.BindingResult;
import org.springframework.validation.FieldError;
import org.springframework.validation.beanvalidation.MethodValidationPostProcessor;
import org.springframework.web.bind.MethodArgumentNotValidException;
import org.springframework.web.bind.annotation.ControllerAdvice;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.ResponseBody;

import com.fortune.base.BaseAPIExcution;

@ControllerAdvice
public class AdviceController implements InitializingBean{
	@Autowired
	private ConfigurableEnvironment env;
	private boolean isDev;
	@ExceptionHandler(value = {BindException.class})
	@ResponseBody
	public ErrorExcution bindException(BindException ex,HttpServletRequest request) {
		if (!isDev) {
			return getErrors();
		}
		BindingResult result = ex.getBindingResult();
		List<FieldError> fieldErrors = result.getFieldErrors();
		StringBuffer msg = new StringBuffer();
		for (FieldError fieldError : fieldErrors) {
			msg.append(fieldError.getDefaultMessage());
		}
		return new ErrorExcution(msg.toString());
	}
	@ExceptionHandler(value = {MethodArgumentNotValidException.class})
	@ResponseBody
	public ErrorExcution methodArgumentNotValidExceptionHandler(MethodArgumentNotValidException ex,HttpServletRequest request) {
		if (!isDev) {
			return getErrors();
		}
		BindingResult result = ex.getBindingResult();
		List<FieldError> fieldErrors = result.getFieldErrors();
		StringBuffer msg = new StringBuffer();
		for (FieldError fieldError : fieldErrors) {
			msg.append(fieldError.getDefaultMessage());
			msg.append(";");
		}
		return new ErrorExcution(msg.toString());
	}
	@ExceptionHandler(value = { ConstraintViolationException.class })
	@ResponseBody
	public ErrorExcution ConstraintViolationExceptionHandle(ConstraintViolationException e) {
		if (!isDev) {
			return getErrors();
		}
		Set<ConstraintViolation<?>> violations = e.getConstraintViolations();
		StringBuilder msg = new StringBuilder();
		for (ConstraintViolation<?> violation : violations) {
			msg.append(violation.getMessage());
			msg.append(";");
		}
		return new ErrorExcution(msg.toString());
	}
	
	@ExceptionHandler(value = { Exception.class })
	@ResponseBody
	public ErrorExcution handleException(Exception e) {
		if (!isDev) {
			return getErrors();
		}
		e.printStackTrace();
		return new ErrorExcution(e.getMessage());
	}

	public static class ErrorExcution extends BaseAPIExcution<Void>{
		public ErrorExcution(String msg) {
			this.status = false;
			this.msg = msg;
		}
	}
	
	private ErrorExcution getErrors() {
		return new ErrorExcution("系统异常");
	}
	
	@Bean
	public MethodValidationPostProcessor methodValidationPostProcessor() {
	    return new MethodValidationPostProcessor();
	}
	@Override
	public void afterPropertiesSet() throws Exception {
		isDev = true;
		String[] profiles = env.getActiveProfiles();
		for (int i = 0; i < profiles.length; i++) {
			if (profiles[i].equals("prod")) {
				isDev=false;
			}
		}
	}
}
